package com.hzhr.iot.log.util.generator;

import com.hzhr.iot.core.util.HzhrFileUtil;
import com.hzhr.iot.core.util.HzhrStringUtils;
import com.hzhr.iot.log.entity.LogEntity;
import com.hzhr.iot.log.util.ReflectUtil;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;

public class CommonMapperGenerator {
    private static String projectName = "log-service";


    public static List<String> guanxi = new ArrayList<String>() {
        {
            add("equal"); add("notequal"); add("like"); add("notlike");
            add("in"); add("notin"); add("greaterthan"); add("greaterthanorequal");
            add("lessthan"); add("lessthanorequal"); add("isnull");
        }
    };
    //current serial : 12
    public static List<GeneratorModel1> generatorModels_2 = new ArrayList<GeneratorModel1>() {
        {
//            add(new GeneratorModel1(ActionEntity.class, 2, 2));
//            add(new GeneratorModel1(ActioninroleEntity.class, 2, 2));
//            add(new GeneratorModel1(CompanyEntity.class, 2, 2));
//            add(new GeneratorModel1(DeptEntity.class, 2, 2,
//                    new AssociationModel(CompanyEntity.class, "companyModel", 6)
//                    ));
//            add(new GeneratorModel1(RoleEntity.class, 2, 2,
//                    new AssociationModel(ActionEntity.class, "actionModelList", 1)
//                    ));
//            add(new GeneratorModel1(OptionsEntity.class, 2, 2));
//            add(new GeneratorModel1(UserEntity.class, 2, 2,
//                    new AssociationModel(RoleEntity.class, "roleModelList", 2),
//                    new AssociationModel(ActionEntity.class, "actionModelList", 3),
//                    new AssociationModel(DeptEntity.class, "deptModel", 4),
//                    new AssociationModel(CompanyEntity.class, "companyModel", 5)
//                    ));
//            add(new GeneratorModel1(UserinroleEntity.class, 2, 2));

            add(new GeneratorModel1(LogEntity.class, 0, 5 ));
        }
    };

    public static void main(String[] args) throws Exception {
        //第一步
//        generateExt();
//        generateQueryModel();

        //第二步
//        generateColumnMapper();
////        generateQueryMapper();
////        generateOrderMapper();
////        generateSetMapper();
////        generateCustomMapper();
    }

    public static void generateExt() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        rootPath += "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");
        String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");

        for (GeneratorModel1 generatorModel : generatorModels_2) {
            Class entityClass = generatorModel.getMainEntityClass();
            String resourceName = entityClass.getSimpleName().substring(0, entityClass.getSimpleName().lastIndexOf("Entity"));

            //生成Ext
            String content1 = "package " + rootPackageName + ".entity.ext;\n";
            content1 += "\n";
            content1 += "import " + rootPackageName + ".entity." + resourceName + "Entity;\n";
            content1 += "import java.util.List;\n";
            content1 += "\n";
            content1 += "public class " + resourceName + "EntityExt extends " + resourceName + "Entity {\n";
            List<AssociationModel> associationModels = generatorModel.getAssociationModels();
            for (AssociationModel associationModel : associationModels) {
                Class<?> entityClass1 = associationModel.getEntityClass();
                String propName = associationModel.getPropName();
                String extName = entityClass1.getSimpleName() + "Ext";
                if (propName.endsWith("Ext")) {
                    content1 += "    private " + extName + " " + propName + ";\n";
                }
                if (propName.endsWith("ExtList")) {
                    content1 += "    private List<" + extName + "> " + propName + ";\n";
                }
            }
            content1 += "\n";
            for (AssociationModel associationModel : associationModels) {
                Class<?> entityClass1 = associationModel.getEntityClass();
                String propName = associationModel.getPropName();
                String extName = entityClass1.getSimpleName() + "Ext";
                if (propName.endsWith("Ext")) {
                    content1 += "    public " + extName + " get" + HzhrStringUtils.firstCharToUppserCase(propName) + "() { return " + propName + "; }\n";
                    content1 += "    public void set" + HzhrStringUtils.firstCharToUppserCase(propName) + "(" + extName + " " + propName + ") { this." + propName + " = " + propName + "; }\n";
                }
                if (propName.endsWith("ExtList")) {
                    content1 += "    public List<" + extName + "> get" + HzhrStringUtils.firstCharToUppserCase(propName) + "() { return " + propName + "; }\n";
                    content1 += "    public void set" + HzhrStringUtils.firstCharToUppserCase(propName) + "(List<" + extName + "> " + propName + ") { this." + propName + " = " + propName + "; }\n";
                }
            }
            content1 += "}\n";
            HzhrFileUtil.writeContent(rootPath + "\\entity\\ext\\" + resourceName + "EntityExt.java", content1);
        }

    }

    public static void generateQueryModel() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        rootPath += "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");
        String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");

        List<Integer> ids = getEntityIds(null);

        for (GeneratorModel1 generatorModel : generatorModels_2) {
            StringBuilder sb = new StringBuilder();
            StringBuilder packageSb = new StringBuilder();
            StringBuilder importSb = new StringBuilder();
            StringBuilder fieldSb = new StringBuilder();
            StringBuilder extFieldSb = new StringBuilder();
            StringBuilder orderFieldSb = new StringBuilder();
            StringBuilder setFieldSb = new StringBuilder();
            StringBuilder pageFieldSb = new StringBuilder();
            StringBuilder functionSb = new StringBuilder();

            packageSb.append("package " + rootPackageName +".queryModel;\n");
            Class entityClass = generatorModel.getMainEntityClass();
            String resourceName = entityClass.getSimpleName().substring(0, entityClass.getSimpleName().lastIndexOf("Entity"));
            Field[] fields = entityClass.getDeclaredFields();
//            for (Field field : fields) {
//                String typeName = field.getType().getSimpleName();
//                String fieldName = field.getName();
//                fieldSb.append("    private " + typeName + " equal_"  + fieldName + ";\n");
//                fieldSb.append("    private " + typeName + " like_"  + fieldName + ";\n");
//                fieldSb.append("    private " + typeName + " greaterthanorequal_"  + fieldName + ";\n");
//                fieldSb.append("    private " + typeName + " lessthan_"  + fieldName + ";\n");
//                fieldSb.append("    private List<" + typeName + "> in_"  + fieldName + ";\n");
//
//                orderFieldSb.append("    private String orderBy_" + fieldName + ";\n");
//
//                setFieldSb.append("    private String set_" + fieldName + ";\n");
//
//                functionSb.append("    public " + typeName + " getEqual_" + fieldName + "() { return equal_" + fieldName + "; }\n");
//                functionSb.append("    public void setEqual_" + fieldName + "(" + typeName + " equal_" + fieldName + ") { this.equal_" + fieldName + " = equal_" + fieldName + "; }\n");
//                functionSb.append("    public " + typeName + " getLike_" + fieldName + "() { return like_" + fieldName + "; }\n");
//                functionSb.append("    public void setLike_" + fieldName + "(" + typeName + " like_" + fieldName + ") { this.like_" + fieldName + " = like_" + fieldName + "; }\n");
//                functionSb.append("    public " + typeName + " getGreaterthanorequal_" + fieldName + "() { return greaterthanorequal_" + fieldName + "; }\n");
//                functionSb.append("    public void setGreaterthanorequal_" + fieldName + "(" + typeName + " greaterthanorequal_" + fieldName + ") { this.greaterthanorequal_" + fieldName + " = greaterthanorequal_" + fieldName + "; }\n");
//                functionSb.append("    public " + typeName + " getLessthan_" + fieldName + "() { return lessthan_" + fieldName + "; }\n");
//                functionSb.append("    public void setLessthan_" + fieldName + "(" + typeName + " lessthan_" + fieldName + ") { this.lessthan_" + fieldName + " = lessthan_" + fieldName + "; }\n");
//                functionSb.append("    public List<" + typeName + "> getIn_" + fieldName + "() { return in_" + fieldName + "; }\n");
//                functionSb.append("    public void setIn_" + fieldName + "(List<" + typeName + "> in_" + fieldName + ") { this.in_" + fieldName + " = in_" + fieldName + "; }\n");
//                functionSb.append("    public String getOrderBy_" + fieldName + "() { return orderBy_" + fieldName + "; }\n");
//                functionSb.append("    public void setOrderBy_" + fieldName + "(String orderBy_" + fieldName + ") { this.orderBy_" + fieldName + " = orderBy_" + fieldName + "; }\n");
//                functionSb.append("    public String getSet_" + fieldName + "() { return set_" + fieldName + "; }\n");
//                functionSb.append("    public void setSet_" + fieldName + "(String set_" + fieldName + ") { this.set_" + fieldName + " = set_" + fieldName + "; }\n");
//            }

            List<String> entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());

//            List<AssociationModel> associationModels = generatorModel.getAssociationModels();
//            if (associationModels != null && associationModels.size() > 0) {
//                for (AssociationModel associationModel:associationModels) {
//                    generateQueryModel_sub1(extFieldSb, functionSb, fieldSb, orderFieldSb, setFieldSb, generatorModel,
//                            associationModel, null, 1, entityClassNameList);
//                }
//            }

            pageFieldSb.append("    private Integer start;\n");
            pageFieldSb.append("    private Integer count;\n");
            pageFieldSb.append("    private Boolean show;\n");
            for (Integer id : ids) {
                pageFieldSb.append("    private Boolean show" + id + ";\n");
            }
            functionSb.append("    public Integer getStart() { return start; }\n");
            functionSb.append("    public void setStart(Integer start) { this.start = start; }\n");
            functionSb.append("    public Integer getCount() { return count; }\n");
            functionSb.append("    public void setCount(Integer count) { this.count = count; }\n");
            functionSb.append("    public void setPage(Integer page, Integer count) {\n");
            functionSb.append("        if (page != null && count != null && page > 0 && count > 0) {\n");
            functionSb.append("            this.start = (page - 1) * count;\n");
            functionSb.append("            this.count = count;\n");
            functionSb.append("        }\n");
            functionSb.append("    }\n");
            functionSb.append("    public Boolean getShow() { return show; }\n");
            functionSb.append("    public void setShow(Boolean show) { this.show = show; }\n");
            for (Integer id : ids) {
                functionSb.append("    public Boolean getShow" + id + "() { return show" + id + "; }\n");
                functionSb.append("    public void setShow" + id + "(Boolean show" + id + ") { this.show" + id + " = show" + id + "; }\n");
            }

            sb.append(packageSb + "\n"
                    + importSb + "\n"
                    + "public class " + resourceName + "QueryModel {\n"
                    + pageFieldSb
                    + "\n"
                    + functionSb + "}");
            HzhrFileUtil.writeContent(rootPath + "\\queryModel\\" + resourceName +"QueryModel.java", sb.toString());

            //生成CustomQueryModel
            String content1 = "package " + rootPackageName + ".queryModel.custom;\n";
            content1 += "\n";
            content1 += "import " + rootPackageName + ".queryModel." + resourceName + "QueryModel;\n";
            content1 += "\n";
            content1 += "public class " + resourceName + "CustomQueryModel extends " + resourceName + "QueryModel {\n";
            content1 += "}\n";
            File file1 = new File(rootPath + "\\queryModel\\custom\\" + resourceName + "CustomQueryModel.java");
            if (!file1.exists()) {
                HzhrFileUtil.writeContent(rootPath + "\\queryModel\\custom\\" + resourceName + "CustomQueryModel.java", content1);
            }
        }
    }
    private static void generateQueryModel_sub1(StringBuilder extFieldSb, StringBuilder functionSb, StringBuilder fieldSb, StringBuilder orderFieldSb,
                                                StringBuilder setFieldSb, GeneratorModel1 generatorModel, AssociationModel associationModel,
                                                String parent, int parentLevel, List<String> entityClassNameList) {
        Class associationEntityClass = associationModel.getEntityClass();
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();

        Field[] fields1 = associationEntityClass.getDeclaredFields();

        extFieldSb.append("    private Boolean ext_" + propName + ";\n");
        extFieldSb.append("    private Boolean update_" + propName + ";\n");
        extFieldSb.append("    private Boolean delete_" + propName + ";\n");
        functionSb.append("    public Boolean getExt_" + propName + "() { return ext_" + propName + "; }\n");
        functionSb.append("    public void setExt_" + propName + "(Boolean ext_" + propName + ") { this.ext_" + propName + " = ext_" + propName + "; }\n");
        functionSb.append("    public Boolean getUpdate_" + propName + "() { return update_" + propName + "; }\n");
        functionSb.append("    public void setUpdate_" + propName + "(Boolean update_" + propName + ") { this.update_" + propName + " = update_" + propName + "; }\n");
        functionSb.append("    public Boolean getDelete_" + propName + "() { return delete_" + propName + "; }\n");
        functionSb.append("    public void setDelete_" + propName + "(Boolean delete_" + propName + ") { this.delete_" + propName + " = delete_" + propName + "; }\n");

        if (parentLevel >= generatorModel.getLevel()) return;
//        for (Field field : fields1) {
//            String typeName = field.getType().getSimpleName();
//            String fieldName = field.getName();
//            fieldSb.append("    private " + typeName + " equal_" + propName + "_" + fieldName + ";\n");
//            fieldSb.append("    private " + typeName + " like_" + propName + "_" + fieldName + ";\n");
//            fieldSb.append("    private " + typeName + " greaterthanorequal_" + propName + "_" + fieldName + ";\n");
//            fieldSb.append("    private " + typeName + " lessthan_" + propName + "_" + fieldName + ";\n");
//            fieldSb.append("    private List<" + typeName + "> in_" + propName + "_" + fieldName + ";\n");
//
//            orderFieldSb.append("    private String orderBy_" + propName + "_" + fieldName + ";\n");
//
//            setFieldSb.append("    private String set_" + propName + "_" + fieldName + ";\n");
//
//            functionSb.append("    public " + typeName + " getEqual_" + propName + "_" + fieldName + "() { return equal_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public void setEqual_" + propName + "_" + fieldName + "(" + typeName + " equal_" + propName + "_" + fieldName + ") { this.equal_" + propName + "_" + fieldName + " = equal_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public " + typeName + " getLike_" + propName + "_" + fieldName + "() { return like_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public void setLike_" + propName + "_" + fieldName + "(" + typeName + " like_" + propName + "_" + fieldName + ") { this.like_" + propName + "_" + fieldName + " = like_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public " + typeName + " getGreaterthanorequal_" + propName + "_" + fieldName + "() { return greaterthanorequal_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public void setGreaterthanorequal_" + propName + "_" + fieldName + "(" + typeName + " greaterthanorequal_" + propName + "_" + fieldName + ") { this.greaterthanorequal_" + propName + "_" + fieldName + " = greaterthanorequal_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public " + typeName + " getLessthan_" + propName + "_" + fieldName + "() { return lessthan_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public void setLessthan_" + propName + "_" + fieldName + "(" + typeName + " lessthan_" + propName + "_" + fieldName + ") { this.lessthan_" + propName + "_" + fieldName + " = lessthan_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public List<" + typeName + "> getIn_" + propName + "_" + fieldName + "() { return in_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public void setIn_" + propName + "_" + fieldName + "(List<" + typeName + "> in_" + propName + "_" + fieldName + ") { this.in_" + propName + "_" + fieldName + " = in_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public String getOrderBy_" + propName + "_" + fieldName + "() { return orderBy_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public void setOrderBy_" + propName + "_" + fieldName + "(String orderBy_" + propName + "_" + fieldName + ") { this.orderBy_" + propName + "_" + fieldName + " = orderBy_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public String getSet_" + propName + "_" + fieldName + "() { return set_" + propName + "_" + fieldName + "; }\n");
//            functionSb.append("    public void setSet_" + propName + "_" + fieldName + "(String set_" + propName + "_" + fieldName + ") { this.set_" + propName + "_" + fieldName + " = set_" + propName + "_" + fieldName + "; }\n");
//        }

        if (entityClassNameList.contains(associationEntityClass.getName())) return;
        entityClassNameList.add(associationEntityClass.getName());
        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationEntityClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    generateQueryModel_sub1(extFieldSb, functionSb, fieldSb, orderFieldSb, setFieldSb, generatorModel,
                            associationModel1, propName, parentLevel + 1, entityClassNameList);
                }
            }
        }
    }

    public static void generateColumnMapper() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        rootPath += "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");

        for (GeneratorModel1 generatorModel : generatorModels_2) {
            Class entityClass = generatorModel.getMainEntityClass();

            List<Integer> ids = new ArrayList<>();
            ids.add(0);
            ids.addAll(getEntityIds(entityClass));

            StringBuilder sb = new StringBuilder();

            String entityName = entityClass.getSimpleName();
            String sourceName = entityName.substring(0, entityName.lastIndexOf("Entity"));

            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
            sb.append("<mapper namespace=\"column." + sourceName + "\">\n");
            for (int i : ids) {
                if (i == 0) {
                    sb.append("  <sql id=\"" + i + "\">\n");
                    sb.append("    <choose>\n");
                    sb.append("      <when test=\"show\">\n");
                    Field[] fields = entityClass.getDeclaredFields();
                    Field field1 = null;
                    int k = 0;
                    for (Field field:fields) {
                        String fieldName = field.getName();
                        String databaseFieldName = geDuanTuoFengZiFuChuan(fieldName);
                        if (k == 0) field1 = field;
                        if (k == fields.length - 1) {
                            sb.append("        " + HzhrStringUtils.splitHumpStr(sourceName, "_").toUpperCase() + i + "." + databaseFieldName + " " + databaseFieldName + "\n");
                        } else {
                            sb.append("        " + HzhrStringUtils.splitHumpStr(sourceName, "_").toUpperCase() + i + "." + databaseFieldName + " " + databaseFieldName + ",\n");
                        }
                        k++;
                    }
                    sb.append("      </when>\n");
                    sb.append("      <otherwise>\n");
                    String fieldName = field1.getName();
                    String databaseFieldName = geDuanTuoFengZiFuChuan(fieldName);
                    sb.append("        " + HzhrStringUtils.splitHumpStr(sourceName, "_").toUpperCase() + i + "." + databaseFieldName + " " + databaseFieldName + "\n");
                    sb.append("      </otherwise>\n");
                    sb.append("    </choose>\n");
                    sb.append("  </sql>\n");
                } else {
                    int j = i ;
                    sb.append("  <sql id=\"" + j + "\">\n");
                    sb.append("    <choose>\n");
                    sb.append("      <when test=\"show" + j + "\">\n");
                    Field[] fields = entityClass.getDeclaredFields();
                    Field field1 = null;
                    int k = 0;
                    for (Field field:fields) {
                        String fieldName = field.getName();
                        String databaseFieldName = geDuanTuoFengZiFuChuan(fieldName);
                        if (k == 0) field1 = field;
                        if (k == fields.length - 1) {
                            sb.append("        " + HzhrStringUtils.splitHumpStr(sourceName, "_").toUpperCase() + j + "." + databaseFieldName + " " + databaseFieldName.toUpperCase() + j + "\n");

                        } else {
                            sb.append("        " + HzhrStringUtils.splitHumpStr(sourceName, "_").toUpperCase() + j + "." + databaseFieldName + " " + databaseFieldName.toUpperCase() + j + ",\n");
                        }
                        k++;
                    }
                    sb.append("      </when>\n");
                    sb.append("      <otherwise>\n");
                    String fieldName = field1.getName();
                    String databaseFieldName = geDuanTuoFengZiFuChuan(fieldName);
                    sb.append("        " + HzhrStringUtils.splitHumpStr(sourceName, "_").toUpperCase() + j + "." + databaseFieldName + " " + databaseFieldName.toUpperCase() + j + "\n");
                    sb.append("      </otherwise>\n");
                    sb.append("    </choose>\n");
                    sb.append("  </sql>\n");
                }
            }
            sb.append("</mapper>\n");
            HzhrFileUtil.writeContent(rootPath + "\\mapper\\snippet\\column\\" + HzhrStringUtils.firstCharToUppserCase(sourceName) +"Column.xml", sb.toString());
        }
    }
    private static List<Integer> getEntityIds(Class EntityClass) {
        List<Integer> ids = new ArrayList<>();
        if (EntityClass == null) {
            for (GeneratorModel1 generatorModel : generatorModels_2) {
                for (AssociationModel associationModel : generatorModel.getAssociationModels()) {
                    ids.add(associationModel.getSerial());
                }
            }
        } else {
            for (GeneratorModel1 generatorModel : generatorModels_2) {
                for (AssociationModel associationModel : generatorModel.getAssociationModels()) {
                    if (associationModel.getEntityClass().getName().equals(EntityClass.getName())) {
                        ids.add(associationModel.getSerial());
                    }
                }
            }
        }
        return ids;
    }
    public static void generateQueryMapper() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        rootPath += "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");
        String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
        String customQueryModelRootPakage = rootPackageName + ".queryModel.custom";

        Set<Class<?>> classes = ReflectUtil.getClasses(customQueryModelRootPakage);
        for (Class<?> clazz : classes) {
            String classSimpleName = clazz.getSimpleName();
            String resourceName = classSimpleName.substring(0, classSimpleName.lastIndexOf("CustomQueryModel"));
            String entityName = resourceName + "Entity";
            Class<?> entityClass = Class.forName(rootPackageName + ".entity." + entityName);
            StringBuilder sb = new StringBuilder();

            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
            sb.append("<mapper namespace=\"query." + resourceName + "\">\n");

            Map<String, String> contentMap = new HashMap<>();
            contentMap.put("0", "");
            getContentMap(contentMap, entityClass, "", "");

            for (GeneratorModel1 generatorModel : generatorModels_2) {
                Class<?> mainClass = generatorModel.getMainEntityClass();
                String mainClassSimpleName = mainClass.getSimpleName();
                if (entityName.equals(mainClassSimpleName)) {
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        String fieldName = field.getName();
                        String[] split = fieldName.split("_");
                        String split1 = split[0];


                        if (split1.equals("or")) {

                        } else if (guanxi.contains(split1)) {
                            if (split.length == 2) {
                                String content = contentMap.get("0");
                                if (content == null) content = "";

                                String split2 = split[1];
                                String databaseFieldName = geDuanTuoFengZiFuChuan(split2);
                                if ("equal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " = #{" + fieldName + "} </if>\n";
                                }
                                if ("notequal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " != #{" + fieldName + "} </if>\n";
                                }
                                if ("like".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " like #{" + fieldName + "} </if>\n";
                                }
                                if ("notlike".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " not like #{" + fieldName + "} </if>\n";
                                }
                                if ("in".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null and " + HzhrStringUtils.firstCharToLowerCase(fieldName) + ".size > 0\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " in <foreach collection=\"" + fieldName + "\" item=\"item\" open=\"(\" close=\")\" separator=\",\">  #{item} </foreach> </if>\n";
                                }
                                if ("notin".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null and " + HzhrStringUtils.firstCharToLowerCase(fieldName) + ".size > 0\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " not in <foreach collection=\"" + fieldName + "\" item=\"item\" open=\"(\" close=\")\" separator=\",\">  #{item} </foreach> </if>\n";
                                }
                                if ("greaterthan".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " > #{" + fieldName + "} </if>\n";
                                }
                                if ("greaterthanorequal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " >= #{" + fieldName + "} </if>\n";
                                }
                                if ("lessthan".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " < #{" + fieldName + "} </if>\n";
                                }
                                if ("lessthanorequal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " <= #{" + fieldName + "} </if>\n";
                                }
                                if ("isnull".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null and " + fieldName + "\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " is null </if>\n";
                                    content += "    <if test=\"" + fieldName + " != null and !" + fieldName + "\"> and " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " is not null </if>\n";
                                }

                                contentMap.put("0", content);
                            } else {
                                String propName = "";
                                for (int i = 1; i < split.length - 1; i++) {
                                    propName += split[i] + "_";
                                }
                                propName = propName.substring(0, propName.length() - 1);

                                AssociationModel associationModel = getAsso(mainClass, propName);
                                String entityName1 = associationModel.getEntityClass().getSimpleName();
                                String resourceName1 = entityName1.substring(0, entityName1.lastIndexOf("Entity"));
                                Integer serial = associationModel.getSerial();

                                String content = contentMap.get(propName + serial);
                                if (content == null) content = "";

                                String split2 = split[split.length - 1];
                                String databaseFieldName = geDuanTuoFengZiFuChuan(split2);
                                if ("equal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " = #{" + fieldName + "} </if>\n";
                                }
                                if ("notequal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " != #{" + fieldName + "} </if>\n";
                                }
                                if ("like".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " like #{" + fieldName + "} </if>\n";
                                }
                                if ("notlike".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " not like #{" + fieldName + "} </if>\n";
                                }
                                if ("in".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null and " + HzhrStringUtils.firstCharToLowerCase(fieldName) + ".size > 0\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " in <foreach collection=\"" + fieldName + "\" item=\"item\" open=\"(\" close=\")\" separator=\",\">  #{item} </foreach> </if>\n";
                                }
                                if ("notin".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null and " + HzhrStringUtils.firstCharToLowerCase(fieldName) + ".size > 0\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " not in <foreach collection=\"" + fieldName + "\" item=\"item\" open=\"(\" close=\")\" separator=\",\">  #{item} </foreach> </if>\n";
                                }
                                if ("greaterthan".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " > #{" + fieldName + "} </if>\n";
                                }
                                if ("greaterthanorequal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " >= #{" + fieldName + "} </if>\n";
                                }
                                if ("lessthan".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " < #{" + fieldName + "} </if>\n";
                                }
                                if ("lessthanorequal".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " <= #{" + fieldName + "} </if>\n";
                                }
                                if ("isnull".equals(split1)) {
                                    content += "    <if test=\"" + fieldName + " != null and " + fieldName + "\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " is null </if>\n";
                                    content += "    <if test=\"" + fieldName + " != null and !" + fieldName + "\"> and " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial +"." + databaseFieldName + " is not null </if>\n";
                                }

                                contentMap.put(propName + serial, content);
                            }
                        }
                    }
                }
            }


            for (Map.Entry<String, String> entry : contentMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();

                sb.append("  <sql id=\"" + key + "\">\n");
                sb.append(value);
                sb.append("  </sql>\n");
            }

            sb.append("</mapper>\n");
            HzhrFileUtil.writeContent(rootPath + "\\mapper\\snippet\\query\\" + HzhrStringUtils.firstCharToUppserCase(resourceName) +"Query.xml", sb.toString());
        }
    }
    private static AssociationModel getAsso(Class<?> mainClass, String rStr) {
        String[] split = rStr.split("_");
        if (split.length > 1) {
            String split1 = split[0];
            for (GeneratorModel1 generatorModel : generatorModels_2) {
                if (generatorModel.getMainEntityClass().equals(mainClass)) {
                    List<AssociationModel> associationModels = generatorModel.getAssociationModels();
                    for (AssociationModel associationModel : associationModels) {
                        if (associationModel.getPropName().equals(split1)) {
                            return getAsso(associationModel.getEntityClass(), rStr.substring(rStr.indexOf("_") + 1));
                        }
                    }
                }
            }
            throw new RuntimeException("未找到associationModel");
        } else {
            String split1 = split[0];
            for (GeneratorModel1 generatorModel : generatorModels_2) {
                if (generatorModel.getMainEntityClass().equals(mainClass)) {
                    List<AssociationModel> associationModels = generatorModel.getAssociationModels();
                    for (AssociationModel associationModel : associationModels) {
                        if (associationModel.getPropName().equals(split1)) {
                            return associationModel;
                        }
                    }
                }
            }
            throw new RuntimeException("未找到associationModel");
        }
    }
    private static void getContentMap(Map<String, String> contentMap, Class<?> mainClass, String pre, String pre1) {

        for (GeneratorModel1 generatorModel : generatorModels_2) {
            if (generatorModel.getMainEntityClass().equals(mainClass)) {
                List<AssociationModel> associationModels = generatorModel.getAssociationModels();
                if (associationModels == null || associationModels.size() == 0) return;
                for (AssociationModel associationModel : associationModels) {
                    Class<?> mainClass1 = associationModel.getEntityClass();
                    String propName = associationModel.getPropName();
                    Integer serial = associationModel.getSerial();

                    if (StringUtils.isEmpty(pre)) {
                        contentMap.put(propName + serial, "");
                    } else {
                        contentMap.put(pre + "_" + propName + serial, "");
                    }
                }
                for (AssociationModel associationModel : associationModels) {
                    Class<?> mainClass1 = associationModel.getEntityClass();
                    String propName = associationModel.getPropName();
                    String entityName = mainClass1.getName();
                    Integer serial = associationModel.getSerial();

                    String pre2 = (StringUtils.isEmpty(pre1) ? "" : pre1.split("_")[pre1.split("_").length - 1]) + "_" + propName + serial;
                    if (pre1.contains(pre2)) continue;
                    pre1 = StringUtils.isEmpty(pre1) ? propName + serial : pre1 + "_" + propName + serial;
                    String preTmp = pre;
                    pre = StringUtils.isEmpty(pre) ? propName : pre + "_" + propName;
                    getContentMap(contentMap, mainClass1, pre, pre1);
                    pre = preTmp;
                }
            }
        }
    }
    private static void generateQueryMapper_sub1(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel,
                                                 String parent, int parentLevel, List<String> entityClassNameList) {
        if (parentLevel >= generatorModel.getLevel()) return;

        Class entityClass = generatorModel.getMainEntityClass();
        int mode = generatorModel.getMode();
        String entityName = entityClass.getSimpleName();

        Class associationClass = associationModel.getEntityClass();
        String sourceName = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
        int j = associationModel.getSerial();
        Field[] fields = associationClass.getDeclaredFields();

        sb.append("  <sql id=\"" + propName + associationModel.getSerial() + "\">\n");
        sb.append("    <if test=\"ext_" + propName + " != null\">\n");
        for (Field field:fields) {
            String fieldName = field.getName();
            String databaseFieldName = geDuanTuoFengZiFuChuan(fieldName);
            if (mode > 0) {
                sb.append("      <if test=\"equal_" + propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " = #{equal_"+ propName + "_" + fieldName + "} </if>\n");
                sb.append("      <if test=\"like_"+ propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " like #{like_"+ propName  + "_" + fieldName + "} </if>\n");
                sb.append("      <if test=\"in_"+ propName + "_" + fieldName + " != null and in_" + HzhrStringUtils.firstCharToLowerCase(fieldName) + ".size > 0\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + j + "." + databaseFieldName + " in <foreach collection=\"in_"+ propName  + "_" + fieldName + "\" item=\"item\" open=\"(\" close=\")\" separator=\",\">  #{item} </foreach> </if>\n");
            }
            if (mode > 1) {
                sb.append("      <if test=\"greaterthanorequal_"+ propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " &gt;= #{greaterthanorequal_"+ propName + "_" + fieldName + "} </if>\n");
                sb.append("      <if test=\"lessthan_"+ propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " &lt; #{lessthan_"+ propName + "_" + fieldName + "} </if>\n");
            }
            if (mode > 2) {
                sb.append("      <if test=\"notequal_"+ propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " != #{notequal_"+ propName + "_" + fieldName + "} </if>\n");
                sb.append("      <if test=\"notlike_"+ propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " not like #{notlike_"+ propName + "_" + fieldName + "} </if>\n");
                sb.append("      <if test=\"notin_"+ propName + "_" + fieldName + " != null and notin_" + HzhrStringUtils.firstCharToLowerCase(fieldName) + ".size > 0\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + j + "." + databaseFieldName + " not in <foreach collection=\"notin_"+ propName + "_" + fieldName + "\" item=\"item\" open=\"(\" close=\")\" separator=\",\">  #{item} </foreach> </if>\n");
            }
            if (mode > 3) {
                sb.append("      <if test=\"greaterthan_"+ propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " &gt; #{greaterthan_"+ propName  + "_" + fieldName + "} </if>\n");
                sb.append("      <if test=\"lessthanorequal_"+ propName + "_" + fieldName + " != null\"> and " + HzhrStringUtils.firstCharToLowerCase(sourceName) + "" + j + "." + databaseFieldName + " &lt;= #{lessthanorequal_"+ propName + "_" + fieldName + "} </if>\n");
            }
        }
        sb.append("    </if>\n");
        sb.append("  </sql>\n");

        if (entityClassNameList.contains(entityClass.getName())) return;
        entityClassNameList.add(entityClass.getName());
        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    generateQueryMapper_sub1(sb, generatorModel, associationModel1, propName, parentLevel + 1, entityClassNameList);
                }
            }
        }
    }

    public static void generateOrderMapper() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        rootPath += "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");
        String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
        String customQueryModelRootPakage = rootPackageName + ".queryModel.custom";

        Set<Class<?>> classes = ReflectUtil.getClasses(customQueryModelRootPakage);
        for (Class<?> clazz : classes) {
            String classSimpleName = clazz.getSimpleName();
            String resourceName = classSimpleName.substring(0, classSimpleName.lastIndexOf("CustomQueryModel"));
            String entityName = resourceName + "Entity";
            Class<?> entityClass = Class.forName(rootPackageName + ".entity." + entityName);
            StringBuilder sb = new StringBuilder();

            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
            sb.append("<mapper namespace=\"order." + resourceName + "\">\n");

            Map<String, String> contentMap = new HashMap<>();
            contentMap.put("0", "");
            getContentMap(contentMap, entityClass, "", "");

            for (GeneratorModel1 generatorModel : generatorModels_2) {
                Class<?> mainClass = generatorModel.getMainEntityClass();
                String mainClassSimpleName = mainClass.getSimpleName();
                if (entityName.equals(mainClassSimpleName)) {
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        String fieldName = field.getName();
                        String[] split = fieldName.split("_");
                        String split1 = split[0];

                        if (!"orderBy".equals(split1)) continue;
                        if (split.length == 2) {
                            String content = contentMap.get("0");
                            if (content == null) content = "";

                            String split2 = split[1];
                            String databaseFieldName = geDuanTuoFengZiFuChuan(split2);

                            content += "      <if test=\"" + fieldName + " != null\"> order by " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " ${" + fieldName + "} </if>\n";

                            contentMap.put("0", content);
                        } else {
                            String propName = "";
                            for (int i = 1; i < split.length - 1; i++) {
                                propName += split[i] + "_";
                            }
                            propName = propName.substring(0, propName.length() - 1);

                            AssociationModel associationModel = getAsso(mainClass, propName);
                            String entityName1 = associationModel.getEntityClass().getSimpleName();
                            String resourceName1 = entityName1.substring(0, entityName1.lastIndexOf("Entity"));
                            Integer serial = associationModel.getSerial();

                            String content = contentMap.get(propName + serial);
                            if (content == null) content = "";

                            String split2 = split[split.length - 1];
                            String databaseFieldName = geDuanTuoFengZiFuChuan(split2);

                            content += "      <if test=\"" + fieldName + " != null\"> order by " + HzhrStringUtils.splitHumpStr(resourceName1, "_").toUpperCase() + serial + "." + databaseFieldName + " ${" + fieldName + "} </if>\n";

                            contentMap.put(propName + serial, content);
                        }
                    }
                }
            }
            for (Map.Entry<String, String> entry : contentMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();

                sb.append("  <sql id=\"" + key + "\">\n");
                sb.append(value);
                sb.append("  </sql>\n");
            }

            sb.append("</mapper>\n");
            HzhrFileUtil.writeContent(rootPath + "\\mapper\\snippet\\order\\" + HzhrStringUtils.firstCharToUppserCase(resourceName) +"Order.xml", sb.toString());
        }
    }
    private static void generateOrderMapper_sub1(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel,
                                                 String parent, int parentLevel, List<String> entityClassNameList) {
        if (parentLevel >= generatorModel.getLevel()) return;

        Class entityClass = generatorModel.getMainEntityClass();
        String entityName = entityClass.getSimpleName();

        Class associationClass = associationModel.getEntityClass();
        String sourceName = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
        int j = associationModel.getSerial();
        Field[] fields = associationClass.getDeclaredFields();

        sb.append("  <sql id=\"" + propName + associationModel.getSerial() + "\">\n");
        sb.append("    <if test=\"ext_" + propName + " != null\">\n");
        for (Field field:fields) {
            String fieldName = field.getName();
            String databaseFieldName = geDuanTuoFengZiFuChuan(fieldName);
            sb.append("      <if test=\"orderBy_" + propName + "_" + fieldName + " != null\"> order by " + HzhrStringUtils.splitHumpStr(sourceName, "_").toUpperCase() + j + "." + databaseFieldName + " ${orderBy_" + propName + "_" + fieldName + "} </if>\n");
        }
        sb.append("    </if>\n");
        sb.append("  </sql>\n");

        if (entityClassNameList.contains(associationClass.getName())) return;
        entityClassNameList.add(associationClass.getName());
        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    generateOrderMapper_sub1(sb, generatorModel, associationModel1, propName, parentLevel + 1, entityClassNameList);
                }
            }
        }
    }
    public static void generateSetMapper() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        rootPath += "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");
        String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
        String customQueryModelRootPakage = rootPackageName + ".queryModel.custom";

        Set<Class<?>> classes = ReflectUtil.getClasses(customQueryModelRootPakage);
        for (Class<?> clazz : classes) {
            String classSimpleName = clazz.getSimpleName();
            String resourceName = classSimpleName.substring(0, classSimpleName.lastIndexOf("CustomQueryModel"));
            String entityName = resourceName + "Entity";
            Class<?> entityClass = Class.forName(rootPackageName + ".entity." + entityName);
            StringBuilder sb = new StringBuilder();

            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
            sb.append("<mapper namespace=\"set." + resourceName + "\">\n");

            Map<String, String> contentMap = new HashMap<>();
            contentMap.put("0", "");
            getContentMap(contentMap, entityClass, "", "");

            for (GeneratorModel1 generatorModel : generatorModels_2) {
                Class<?> mainClass = generatorModel.getMainEntityClass();
                String mainClassSimpleName = mainClass.getSimpleName();
                if (entityName.equals(mainClassSimpleName)) {
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        String fieldName = field.getName();
                        String[] split = fieldName.split("_");
                        String split1 = split[0];

                        if ("set".equals(split1)) {
                            if (split.length == 2) {
                                String content = contentMap.get("0");
                                if (content == null) content = "";

                                String split2 = split[1];
                                String databaseFieldName = geDuanTuoFengZiFuChuan(split2);

                                content += "      <if test=\"" + fieldName + " != null\"> " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " = #{" + fieldName + "}, </if>\n";

                                contentMap.put("0", content);
                            } else {
                                String propName = "";
                                for (int i = 1; i < split.length - 1; i++) {
                                    propName += split[i] + "_";
                                }
                                propName = propName.substring(0, propName.length() - 1);

                                AssociationModel associationModel = getAsso(mainClass, propName);
                                String entityName1 = associationModel.getEntityClass().getSimpleName();
                                String resourceName1 = entityName1.substring(0, entityName1.lastIndexOf("Entity"));
                                Integer serial = associationModel.getSerial();

                                String content = contentMap.get(propName + serial);
                                if (content == null) content = "";

                                String split2 = split[split.length - 1];
                                String databaseFieldName = geDuanTuoFengZiFuChuan(split2);

                                content += "      <if test=\"" + fieldName + " != null\"> " + HzhrStringUtils.firstCharToLowerCase(resourceName1).toUpperCase() + serial + "." + databaseFieldName + " = #{" + fieldName + "}, </if>\n";

                                contentMap.put(propName + serial, content);
                            }
                        } else if ("setnull".equals(split1)) {
                            if (split.length == 2) {
                                String content = contentMap.get("0");
                                if (content == null) content = "";

                                String split2 = split[1];
                                String databaseFieldName = geDuanTuoFengZiFuChuan(split2);

                                content += "      <if test=\"" + fieldName + "\"> " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0." + databaseFieldName + " = null, </if>\n";

                                contentMap.put("0", content);
                            } else {
                                String propName = "";
                                for (int i = 1; i < split.length - 1; i++) {
                                    propName += split[i] + "_";
                                }
                                propName = propName.substring(0, propName.length() - 1);

                                AssociationModel associationModel = getAsso(mainClass, propName);
                                String entityName1 = associationModel.getEntityClass().getSimpleName();
                                String resourceName1 = entityName1.substring(0, entityName1.lastIndexOf("Entity"));
                                Integer serial = associationModel.getSerial();

                                String content = contentMap.get(propName + serial);
                                if (content == null) content = "";

                                String split2 = split[split.length - 1];
                                String databaseFieldName = geDuanTuoFengZiFuChuan(split2);

                                content += "      <if test=\"" + fieldName + "\"> " + HzhrStringUtils.firstCharToLowerCase(resourceName1).toUpperCase() + serial + "." + databaseFieldName + " = null, </if>\n";

                                contentMap.put(propName + serial, content);
                            }
                        }
                    }
                }
            }
            for (Map.Entry<String, String> entry : contentMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();

                sb.append("  <sql id=\"" + key + "\">\n");
                sb.append("    <set>\n");
                sb.append(value);
                sb.append("    </set>\n");
                sb.append("  </sql>\n");
            }

            sb.append("</mapper>\n");
            HzhrFileUtil.writeContent(rootPath + "\\mapper\\snippet\\set\\" + HzhrStringUtils.firstCharToUppserCase(resourceName) +"Set.xml", sb.toString());
        }
    }
    private static void generateSetMapper_sub1(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel,
                                               String parent, int parentLevel, List<String> entityClassNameList) {
        if (parentLevel >= generatorModel.getLevel()) return;

        Class entityClass = generatorModel.getMainEntityClass();
        String entityName = entityClass.getSimpleName();

        Class associationClass = associationModel.getEntityClass();
        String sourceName = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
        int j = associationModel.getSerial();
        Field[] fields = associationClass.getDeclaredFields();

        sb.append("  <sql id=\"" + propName + associationModel.getSerial() + "\">\n");
        sb.append("    <if test=\"update_" + propName + " != null\">\n");
        for (Field field:fields) {
            String fieldName = field.getName();
            String databaseFieldName = geDuanTuoFengZiFuChuan(fieldName);
            sb.append("      <if test=\"set_" + propName + "_" + fieldName + " != null\"> set " + HzhrStringUtils.firstCharToLowerCase(sourceName) + j + "." + databaseFieldName + "= #{set_" + propName + "_" + fieldName + "} </if>\n");
        }
        sb.append("    </if>\n");
        sb.append("  </sql>\n");

        if (entityClassNameList.contains(associationClass.getName())) return;
        entityClassNameList.add(associationClass.getName());
        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    generateSetMapper_sub1(sb, generatorModel, associationModel1, propName, parentLevel + 1, entityClassNameList);
                }
            }
        }
    }

    public static void generateCustomMapper() throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        String srcRootPath = rootPath + "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");
        String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");

        for (GeneratorModel1 generatorModel : generatorModels_2) {
            StringBuilder sb = new StringBuilder();
            List<AssociationModel> associationModels = generatorModel.getAssociationModels();
            Class<?> mainEntityClass = generatorModel.getMainEntityClass();
            String mainEntityClassName = mainEntityClass.getSimpleName();
            String resourceName = mainEntityClassName.substring(0, mainEntityClassName.lastIndexOf("Entity"));

            sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            sb.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
            sb.append("<mapper namespace=\"custom." + resourceName + "\">\n");
            sb.append("  <resultMap id=\"ext\" type=\"" + rootPackageName + ".entity.ext." + mainEntityClassName + "Ext\">\n");

            String insertBatchData = "";
            String updateBatchData = "";
            String updateBatchData1 = "";

            List<String> resourceNameList = new ArrayList<>();
            String exampleMapperRootPath = srcRootPath + "\\mapper\\generator";
            List<File> files = HzhrFileUtil.getFiles(exampleMapperRootPath);
            for (File file : files) {//遍历example
                String tablenaName = null;

                if (file.getName().substring(0, file.getName().lastIndexOf("EntityMapper.xml")).equals(resourceName)) {
                    //读取xml
                    InputStream in = new FileInputStream(file);
                    SAXReader reader = new SAXReader();
                    reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
                    Document doc = reader.read(in);

                    Element root = doc.getRootElement();
                    List<Element> elementList = root.elements();
                    for (Element element : elementList) {
                        String id = element.attributeValue("id");
                        if ("BaseResultMap".equals(id)) {
                            List<Element> elementList1 = element.elements();
                            for (Element element1:elementList1) {
                                String name = element1.getName();
                                String column = element1.attributeValue("column");
                                String jdbcType = element1.attributeValue("jdbcType");
                                String property = element1.attributeValue("property");
                                if (name.equals("id")) {
                                    sb.append("    <id column=\"" + column + "\" jdbcType=\"" + jdbcType + "\" property=\"" + property + "\" />\n");
                                } else {
                                    sb.append("    <result column=\"" + column + "\" jdbcType=\"" + jdbcType + "\" property=\"" + property + "\" />\n");
                                }
                            }
                        }
                    }



                    for (Element element : elementList) {
                        String id = element.attributeValue("id");
                        if ("insert".equals(id)) {
                            String data = element.getData().toString();

                            tablenaName = data.substring(data.indexOf("insert into") + 12, data.indexOf("(") - 1);

                            String sub1 = data.substring(data.indexOf("insert into"), data.indexOf("values (") + 6);
                            sub1 = "    " + sub1;
                            String sub2 = data.substring(data.indexOf("values (") + 6, data.lastIndexOf(")") + 1);
                            sub2 = "\n    <foreach collection =\"list\" item=\"item\" separator =\",\">\n    " + sub2;
                            sub2 += "\n    </foreach >";
                            sub2 = sub2.replace("#{", "#{item.");
                            insertBatchData += sub1 + sub2 + "\n";
                        }
                    }

                    for (Element element : elementList) {
                        String id = element.attributeValue("id");
                        String idJdbc = null;

                        if ("BaseResultMap".equals(id)) {
                            updateBatchData += "    <foreach collection=\"list\" separator=\";\" item=\"cus\">\n";
                            updateBatchData += "      update " + tablenaName + " set\n";
                            List<Element> baseMapEles = element.elements();
                            for (Element baseMapEle : baseMapEles) {
                                if (baseMapEle.getName().equals("id")) {
                                    idJdbc = baseMapEle.attributeValue("jdbcType");
                                    continue;
                                }

                                String column = baseMapEle.attributeValue("column");
                                String jdbcType = baseMapEle.attributeValue("jdbcType");
                                String property = baseMapEle.attributeValue("property");

                                updateBatchData += "      " + column + " = #{cus." + property + ",jdbcType=" + jdbcType + "},\n";

                            }
                            updateBatchData = updateBatchData.substring(0, updateBatchData.length() - 2);
                            updateBatchData += "\n";
                            updateBatchData += "      where id = #{cus.id}\n";
                            updateBatchData += "    </foreach>\n";

                            updateBatchData1 += "    <foreach collection=\"list\" separator=\";\" item=\"cus\">\n";
                            updateBatchData1 += "      update " + tablenaName + "\n";
                            updateBatchData1 += "      <set>\n";
                            for (Element baseMapEle : baseMapEles) {
                                if (baseMapEle.getName().equals("id")) {
                                    idJdbc = baseMapEle.attributeValue("jdbcType");
                                    continue;
                                }

                                String column = baseMapEle.attributeValue("column");
                                String jdbcType = baseMapEle.attributeValue("jdbcType");
                                String property = baseMapEle.attributeValue("property");

                                updateBatchData1 += "        <if test=\"cus." + property + " != null\">" + column + " = #{cus." + property + ",jdbcType=" + jdbcType + "},</if>\n";
                            }
                            updateBatchData1 += "      </set>\n";
                            updateBatchData1 += "      where id = #{cus.id}\n";
                            updateBatchData1 += "    </foreach>\n";
                        }
                    }
                }
            }
            for (AssociationModel associationModel : associationModels) {
                Class associationClass = associationModel.getEntityClass();
                String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
                String propName = associationModel.getPropName();
                int ser = associationModel.getSerial();

                sb.append("    <association property=\"" + propName + "\" resultMap=\"" + HzhrStringUtils.firstCharToLowerCase(resourceName1) + ser + "_" + "ext\" />\n");
            }
            sb.append("  </resultMap>\n");

            List<String> entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            List<String> nameList = new ArrayList<>();
            for (AssociationModel associationModel : associationModels) {
                generateCustomMapper_sub0(sb, associationModel, nameList);
            }

            //selectMain
            entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            sb.append("  <sql id=\"selectMain\">\n");
            sb.append("    <include refid=\"column." + resourceName + ".0\"/>\n");
            for (AssociationModel associationModel : associationModels) {
                generateCustomMapper_sub1(sb, generatorModel, associationModel, null, "");
            }
            sb.append("  </sql>\n");

            //updateMain
            entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            sb.append("  <sql id=\"updateMain\">\n");
            sb.append("    " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + " " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0\n");
            sb.append("    <include refid=\"" + rootPackageName + ".dao.mapper.custom." + resourceName + "EntityCustomMapper.fromExt\" />\n");
            for (AssociationModel associationModel : associationModels) {
                generateCustomMapper_sub2(sb, generatorModel, associationModel, null, "");
            }
            sb.append("  </sql>\n");

            //delMain
            entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            sb.append("  <sql id=\"delMain\">\n");
            sb.append("    " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0\n");
            for (AssociationModel associationModel : associationModels) {
                generateCustomMapper_sub3(sb, generatorModel, associationModel, null, "");
            }
            sb.append("  </sql>\n");

            //from
            entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            sb.append("  <sql id=\"from\">\n");
            sb.append("    " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + " " + HzhrStringUtils.splitHumpStr(resourceName, "_").toUpperCase() + "0\n");
            sb.append("    <include refid=\"" + rootPackageName + ".dao.mapper.custom." + resourceName + "EntityCustomMapper.fromExt\" />\n");
            sb.append("  </sql>\n");

            //set
            entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            sb.append("  <sql id=\"set\">\n");
            sb.append("    <include refid=\"set." + resourceName + ".0\"/>\n");
            for (AssociationModel associationModel : associationModels) {
                generateCustomMapper_sub4(sb, generatorModel, associationModel, null,  "");
            }
            sb.append("  </sql>\n");

            //query
            entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            sb.append("  <sql id=\"query\">\n");
            sb.append("    <include refid=\"query." + resourceName + ".0\"/>\n");
            for (AssociationModel associationModel : associationModels) {
                generateCustomMapper_sub5(sb, generatorModel, associationModel, null, "");
            }
            sb.append("  </sql>\n");

            //order
            entityClassNameList = new ArrayList<>();
            entityClassNameList.add(generatorModel.getMainEntityClass().getName());
            sb.append("  <sql id=\"order\">\n");
            sb.append("    <include refid=\"order." + resourceName + ".0\"/>\n");
            for (AssociationModel associationModel : associationModels) {
                generateCustomMapper_sub6(sb, generatorModel, associationModel, null,  "");
            }
            sb.append("  </sql>\n");

            //insertBatch
            sb.append("  <sql id=\"insertBatch\">\n");
            sb.append(insertBatchData);
            sb.append("  </sql>\n");

            //updateBatch
            sb.append("  <sql id=\"updateBatch\">\n");
            sb.append(updateBatchData);
            sb.append("  </sql>\n");

            //updateBatch
            sb.append("  <sql id=\"updateBatchSelective\">\n");
            sb.append(updateBatchData1);
            sb.append("  </sql>\n");


            sb.append("</mapper>\n");
            HzhrFileUtil.writeContent(srcRootPath + "\\mapper\\snippet\\custom\\" + resourceName +"Custom.xml", sb.toString());
        }
    }
    private static void generateCustomMapper_sub0(StringBuilder sb, AssociationModel associationModel, List<String> entityClassNameList) throws Exception {
        File directory = new File("");//设定为当前文件夹
        String rootPath = directory.getCanonicalPath();
        String srcRootPath = rootPath + "\\" + projectName + "\\src\\main\\java\\" + CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "").replace(".", "\\");
        String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
        String exampleMapperRootPath = srcRootPath + "\\mapper\\generator";
        Class associationClass = associationModel.getEntityClass();
        String associationClassName = associationClass.getSimpleName();
        String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = associationModel.getPropName();
        int ser = associationModel.getSerial();

        if (entityClassNameList.contains(HzhrStringUtils.firstCharToLowerCase(resourceName1) + ser)) return;
        entityClassNameList.add(HzhrStringUtils.firstCharToLowerCase(resourceName1) + ser);

        sb.append("  <resultMap id=\"" + HzhrStringUtils.firstCharToLowerCase(resourceName1) + ser + "_" + "ext\" type=\"" + rootPackageName + ".entity.ext." + associationClassName + "Ext\">\n");

        List<File> files1 = HzhrFileUtil.getFiles(exampleMapperRootPath);
        for (File file : files1) {//遍历example
            //读取xml
            if (file.getName().substring(0, file.getName().lastIndexOf("EntityMapper.xml")).equals(resourceName1)) {
                InputStream in = new FileInputStream(file);
                SAXReader reader = new SAXReader();
                reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
                Document doc = reader.read(in);

                Element root = doc.getRootElement();
                List<Element> elementList = root.elements();
                for (Element element : elementList) {
                    String id = element.attributeValue("id");
                    if ("BaseResultMap".equals(id)) {
                        List<Element> elementList1 = element.elements();
                        for (Element element1:elementList1) {
                            String name = element1.getName();
                            String column = element1.attributeValue("column") + ser;
                            String jdbcType = element1.attributeValue("jdbcType");
                            String property = element1.attributeValue("property");
                            if (name.equals("id")) {
                                sb.append("    <id column=\"" + column + "\" jdbcType=\"" + jdbcType + "\" property=\"" + property + "\" />\n");
                            } else {
                                sb.append("    <result column=\"" + column + "\" jdbcType=\"" + jdbcType + "\" property=\"" + property + "\" />\n");
                            }
                        }
                    }
                }

                boolean flag = false;
                for (GeneratorModel1 item : generatorModels_2) {
                    Class mainEntityClass = item.getMainEntityClass();
                    if (mainEntityClass.getName().equals(associationClass.getName())) {
                        List<AssociationModel> associationModels = item.getAssociationModels();
                        for (AssociationModel associationModel1 : associationModels) {
                            String propName1 = associationModel1.getPropName();
                            Class associationClass1 = associationModel1.getEntityClass();
                            String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
                            int ser1 = associationModel1.getSerial();

                            sb.append("    <association property=\"" + propName1 + "\" resultMap=\"" + HzhrStringUtils.firstCharToLowerCase(resourceName2) + ser1 + "_" + "ext\" />\n");

                        }
                        sb.append("  </resultMap>\n");
                        flag = true;


                        for (AssociationModel associationModel1 : associationModels) {
                            String propName1 = associationModel1.getPropName();
                            Class associationClass1 = associationModel1.getEntityClass();
                            String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
                            int ser1 = associationModel1.getSerial();
                            generateCustomMapper_sub0(sb, associationModel1, entityClassNameList);
                        }
                    }
                }
                if (!flag) {
                    sb.append("  </resultMap>\n");
                }

            }
        }
    }
    private static void generateCustomMapper_sub1(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel, String parent, String pre) {
        String entityName = generatorModel.getMainEntityClass().getSimpleName();
        String resourceName = entityName.substring(0, entityName.lastIndexOf("Entity"));

        Class associationClass = associationModel.getEntityClass();
        String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
        int ser = associationModel.getSerial();

        try {
            String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
            String customQueryModelRootPakage = rootPackageName + ".queryModel.custom.";
            Class<?> customQueryModelClass = Class.forName(customQueryModelRootPakage + resourceName + "CustomQueryModel");
            Field[] fields = customQueryModelClass.getDeclaredFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                if (fieldName.equals("ext_" + propName)) {
                    sb.append("    <if test=\"ext_" + propName + "\">\n");
                    sb.append("      ,<include refid=\"column." + resourceName1 + "." + ser + "\"/>\n");
                    sb.append("    </if>\n");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    String propName1 = associationModel1.getPropName();
                    Class associationClass1 = associationModel1.getEntityClass();
                    String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
                    int ser1 = associationModel1.getSerial();

                    String pre1 = (StringUtils.isEmpty(pre) ? "" : pre.split("_")[pre.split("_").length - 1]) + "_" + propName1 + ser1;
                    if (pre.contains(pre1)) continue;
                    pre = StringUtils.isEmpty(pre) ? propName1 + ser1 : pre + "_" + propName1 + ser1;

                    generateCustomMapper_sub1(sb, generatorModel, associationModel1, propName, pre);
                }
            }
        }
    }
    private static void generateCustomMapper_sub2(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel, String parent, String pre) {
//        String entityName = generatorModel.getMainEntityClass().getSimpleName();
//        String resourceName = entityName.substring(0, entityName.lastIndexOf("Entity"));
//
//        Class associationClass = associationModel.getEntityClass();
//        String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
//        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
//        int ser = associationModel.getSerial();
//
//
//        try {
//            String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
//            String customQueryModelRootPakage = rootPackageName + ".queryModel.custom.";
//            Class<?> customQueryModelClass = Class.forName(customQueryModelRootPakage + resourceName + "CustomQueryModel");
//            Field[] fields = customQueryModelClass.getDeclaredFields();
//            for (Field field : fields) {
//                String fieldName = field.getName();
//                if (fieldName.equals("ext_" + propName)) {
//                    sb.append("    <if test=\"ext_" + propName + "\">\n");
//                    sb.append("      <include refid=\"query." + resourceName1 + "." + ser + "\"/>\n");
//                    //sb.append("      ," + HzhrStringUtils.firstCharToLowerCase(resourceName1).toUpperCase() + " " + HzhrStringUtils.firstCharToLowerCase(resourceName1).toUpperCase() + ser + "\n");
//                    sb.append("    </if>\n");
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return;
//        }
//
//        for (GeneratorModel1 item : generatorModels_2) {
//            Class mainEntityClass = item.getMainEntityClass();
//            if (mainEntityClass.getName().equals(associationClass.getName())) {
//                List<AssociationModel> associationModels = item.getAssociationModels();
//                for (AssociationModel associationModel1 : associationModels) {
//                    String propName1 = associationModel1.getPropName();
//                    Class associationClass1 = associationModel1.getEntityClass();
//                    String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
//                    int ser1 = associationModel1.getSerial();
//
//                    String pre1 = (StringUtils.isEmpty(pre) ? "" : pre.split("_")[pre.split("_").length - 1]) + "_" + propName1 + ser1;
//                    if (pre.contains(pre1)) continue;
//                    pre = StringUtils.isEmpty(pre) ? propName1 + ser1 : pre + "_" + propName1 + ser1;
//
//                    generateCustomMapper_sub2(sb, generatorModel, associationModel1, propName, pre);
//                }
//            }
//        }
    }
    private static void generateCustomMapper_sub3(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel, String parent, String pre) {
//        String entityName = generatorModel.getMainEntityClass().getSimpleName();
//        String resourceName = entityName.substring(0, entityName.lastIndexOf("Entity"));
//
//        Class associationClass = associationModel.getEntityClass();
//        String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
//        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
//        int ser = associationModel.getSerial();
//
//        try {
//            String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
//            String customQueryModelRootPakage = rootPackageName + ".queryModel.custom.";
//            Class<?> customQueryModelClass = Class.forName(customQueryModelRootPakage + resourceName + "CustomQueryModel");
//            Field[] fields = customQueryModelClass.getDeclaredFields();
//            for (Field field : fields) {
//                String fieldName = field.getName();
//                if (fieldName.equals("ext_" + propName)) {
//                    sb.append("    <if test=\"ext_" + propName + "\">\n");
//                    sb.append("      <include refid=\"query." + resourceName1 + "." + ser + "\"/>\n");
//                    sb.append("      ," + HzhrStringUtils.firstCharToLowerCase(resourceName1).toUpperCase()  + ser + "\n");
//                    sb.append("    </if>\n");
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            return;
//        }
//
//        for (GeneratorModel1 item : generatorModels_2) {
//            Class mainEntityClass = item.getMainEntityClass();
//            if (mainEntityClass.getName().equals(associationClass.getName())) {
//                List<AssociationModel> associationModels = item.getAssociationModels();
//                for (AssociationModel associationModel1 : associationModels) {
//                    String propName1 = associationModel1.getPropName();
//                    Class associationClass1 = associationModel1.getEntityClass();
//                    String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
//                    int ser1 = associationModel1.getSerial();
//
//                    String pre1 = (StringUtils.isEmpty(pre) ? "" : pre.split("_")[pre.split("_").length - 1]) + "_" + propName1 + ser1;
//                    if (pre.contains(pre1)) continue;
//                    pre = StringUtils.isEmpty(pre) ? propName1 + ser1 : pre + "_" + propName1 + ser1;
//
//                    generateCustomMapper_sub3(sb, generatorModel, associationModel1, propName, pre);
//                }
//            }
//        }
    }
    private static void generateCustomMapper_sub4(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel,
                                                  String parent, String pre) {
        Class associationEntityClass = associationModel.getEntityClass();

        String entityName = generatorModel.getMainEntityClass().getSimpleName();
        String resourceName = entityName.substring(0, entityName.lastIndexOf("Entity"));

        Class associationClass = associationModel.getEntityClass();
        String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
        int ser = associationModel.getSerial();

        try {
            String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
            String customQueryModelRootPakage = rootPackageName + ".queryModel.custom.";
            Class<?> customQueryModelClass = Class.forName(customQueryModelRootPakage + resourceName1 + "CustomQueryModel");
            Field[] fields = customQueryModelClass.getDeclaredFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                if (fieldName.equals("update_" + propName)) {
                    sb.append("    <if test=\"update_" + propName + "\">\n");
                    sb.append("      <include refid=\"set." + resourceName + "." + propName + ser + "\"/>\n");
                    sb.append("    </if>\n");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }


        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    String propName1 = associationModel1.getPropName();
                    Class associationClass1 = associationModel1.getEntityClass();
                    String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
                    int ser1 = associationModel1.getSerial();

                    String pre1 = (StringUtils.isEmpty(pre) ? "" : pre.split("_")[pre.split("_").length - 1]) + "_" + propName1 + ser1;
                    if (pre.contains(pre1)) continue;
                    pre = StringUtils.isEmpty(pre) ? propName1 + ser1 : pre + "_" + propName1 + ser1;

                    generateCustomMapper_sub4(sb, generatorModel, associationModel1, propName, pre);
                }
            }
        }
    }
    private static void generateCustomMapper_sub5(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel,
                                                  String parent, String pre) {

        Class associationEntityClass = associationModel.getEntityClass();

        String entityName = generatorModel.getMainEntityClass().getSimpleName();
        String resourceName = entityName.substring(0, entityName.lastIndexOf("Entity"));

        Class associationClass = associationModel.getEntityClass();
        String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
        int ser = associationModel.getSerial();

        try {
            String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
            String customQueryModelRootPakage = rootPackageName + ".queryModel.custom.";
            Class<?> customQueryModelClass = Class.forName(customQueryModelRootPakage + resourceName + "CustomQueryModel");
            Field[] fields = customQueryModelClass.getDeclaredFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                if (fieldName.equals("ext_" + propName)) {
                    sb.append("    <if test=\"ext_" + propName + "\">\n");
                    sb.append("      <include refid=\"query." + resourceName + "." + propName + ser + "\"/>\n");
                    sb.append("    </if>\n");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }


        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    String propName1 = associationModel1.getPropName();
                    Class associationClass1 = associationModel1.getEntityClass();
                    String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
                    int ser1 = associationModel1.getSerial();

                    String pre1 = (StringUtils.isEmpty(pre) ? "" : pre.split("_")[pre.split("_").length - 1]) + "_" + propName1 + ser1;
                    if (pre.contains(pre1)) continue;
                    pre = StringUtils.isEmpty(pre) ? propName1 + ser1 : pre + "_" + propName1 + ser1;

                    generateCustomMapper_sub5(sb, generatorModel, associationModel1, propName, pre);
                }
            }
        }
    }
    private static void generateCustomMapper_sub6(StringBuilder sb, GeneratorModel1 generatorModel, AssociationModel associationModel,
                                                  String parent, String pre) {

        Class associationEntityClass = associationModel.getEntityClass();

        String entityName = generatorModel.getMainEntityClass().getSimpleName();
        String resourceName = entityName.substring(0, entityName.lastIndexOf("Entity"));

        Class associationClass = associationModel.getEntityClass();
        String resourceName1 = associationClass.getSimpleName().substring(0, associationClass.getSimpleName().lastIndexOf("Entity"));
        String propName = parent != null ? parent + "_" + associationModel.getPropName() : associationModel.getPropName();
        int ser = associationModel.getSerial();

        try {
            String rootPackageName = CommonMapperGenerator.class.getPackage().getName().replace(".util.generator", "");
            String customQueryModelRootPakage = rootPackageName + ".queryModel.custom.";
            Class<?> customQueryModelClass = Class.forName(customQueryModelRootPakage + resourceName + "CustomQueryModel");
            Field[] fields = customQueryModelClass.getDeclaredFields();
            for (Field field : fields) {
                String fieldName = field.getName();
                if (fieldName.equals("orderBy_" + propName)) {
                    sb.append("    <if test=\"orderBy_" + propName + "\">\n");
                    sb.append("      <include refid=\"order." + resourceName + "." + propName + ser + "\"/>\n");
                    sb.append("    </if>\n");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }


        for (GeneratorModel1 item : generatorModels_2) {
            Class mainEntityClass = item.getMainEntityClass();
            if (mainEntityClass.getName().equals(associationClass.getName())) {
                List<AssociationModel> associationModels = item.getAssociationModels();
                for (AssociationModel associationModel1 : associationModels) {
                    String propName1 = associationModel1.getPropName();
                    Class associationClass1 = associationModel1.getEntityClass();
                    String resourceName2 = associationClass1.getSimpleName().substring(0, associationClass1.getSimpleName().lastIndexOf("Entity"));
                    int ser1 = associationModel1.getSerial();

                    String pre1 = (StringUtils.isEmpty(pre) ? "" : pre.split("_")[pre.split("_").length - 1]) + "_" + propName1 + ser1;
                    if (pre.contains(pre1)) continue;
                    pre = StringUtils.isEmpty(pre) ? propName1 + ser1 : pre + "_" + propName1 + ser1;

                    generateCustomMapper_sub6(sb, generatorModel, associationModel1, propName, pre);
                }
            }
        }
    }

    public static Integer getSer(GeneratorModel1 generatorModel1, List<String> propNames, int i) {
        Integer ser = 0;
        List<CommonMapperGenerator.AssociationModel> associationModels = generatorModel1.getAssociationModels();
        for (CommonMapperGenerator.AssociationModel associationModel : associationModels) {
            if (associationModel.getPropName().equals(propNames.get(i))) {
                if (propNames.size() > i + 1) {
                    for (CommonMapperGenerator.GeneratorModel1 generatorModel11:
                            CommonMapperGenerator.generatorModels_2) {
                        if (generatorModel11.getMainEntityClass().getName().equals(associationModel.getEntityClass().getName())) {
                            ser = getSer(generatorModel11, propNames, i + 1);
                        }
                    }
                } else {
                    ser = associationModel.getSerial();
                }
            }
        }
        return ser;
    }



    /**
     * 驼峰转驼峰
     */
    private static String geDuanTuoFengZiFuChuan(String str) {
        StringBuilder sb = new StringBuilder();
        char[] cs = str.toCharArray();

        for (int i = 0; i < cs.length; i++) {
            char c = cs[i];
            if (Character.isUpperCase(c)) {
                sb.append("_" + Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }

        return sb.toString();
    }

    static class GeneratorModel {
        private Class<?> entityClass;
        private List<String> extProps;
        //生成模型的数量
        private int count;
        //筛选条件模式
        // 1 极简单(equal、like、in)
        // 2 简单(equal、like、in、greaterthanorequal、lessthan)
        // 3 一般(equal、notequal、like、notlike、in、notin、greaterthanorequal、lessthan)
        // 4 全部
        private int mode;

        public GeneratorModel(Class<?> entityClass, int count, int mode, String... extProps) {
            this.entityClass = entityClass;
            if (extProps != null) {
                this.extProps = Arrays.asList(extProps);
            }
            this.count = count;
            this.mode = mode;
        }

        public Class<?> getEntityClass() {
            return entityClass;
        }

        public void setEntityClass(Class<?> entityClass) {
            this.entityClass = entityClass;
        }

        public List<String> getExtProps() {
            return extProps;
        }

        public void setExtProps(List<String> extProps) {
            this.extProps = extProps;
        }

        public int getCount() {
            return count;
        }

        public void setCount(int count) {
            this.count = count;
        }

        public int getMode() {
            return mode;
        }

        public void setMode(int mode) {
            this.mode = mode;
        }
    }
    static class GeneratorModel1 {
        private Class<?> mainEntityClass;
        private List<AssociationModel> associationModels;
        //筛选条件模式
        // 1 极简单(equal、like、in)
        // 2 简单(equal、like、in、greaterthanorequal、lessthan)
        // 3 一般(equal、notequal、like、notlike、in、notin、greaterthanorequal、lessthan)
        // 4 全部
        private int mode;
        //筛选条件层级：如果为1，则只有本实体的筛选条件，如果为2，则包含第一层关联实体的筛选条件，一次类推
        private int level;

        public GeneratorModel1(Class<?> mainEntityClass, int mode, int level, AssociationModel... associationModels) {
            this.mainEntityClass = mainEntityClass;
            this.mode = mode;
            this.level = level;
            if (associationModels != null) {
                this.associationModels = Arrays.asList(associationModels);
            }
        }

        public Class<?> getMainEntityClass() {
            return mainEntityClass;
        }

        public void setMainEntityClass(Class<?> mainEntityClass) {
            this.mainEntityClass = mainEntityClass;
        }

        public List<AssociationModel> getAssociationModels() {
            return associationModels;
        }

        public void setAssociationModels(List<AssociationModel> associationModels) {
            this.associationModels = associationModels;
        }

        public int getMode() {
            return mode;
        }

        public void setMode(int mode) {
            this.mode = mode;
        }

        public int getLevel() {
            return level;
        }

        public void setLevel(int level) {
            this.level = level;
        }
    }
    static class AssociationModel {
        private Class<?> entityClass;
        private String propName;
        private int serial;

        public AssociationModel(Class<?> entityClass, String propName, int serial) {
            this.entityClass = entityClass;
            this.propName = propName;
            this.serial = serial;
        }

        public Class<?> getEntityClass() {
            return entityClass;
        }

        public void setEntityClass(Class<?> entityClass) {
            this.entityClass = entityClass;
        }

        public String getPropName() {
            return propName;
        }

        public void setPropName(String propName) {
            this.propName = propName;
        }

        public int getSerial() {
            return serial;
        }

        public void setSerial(int serial) {
            this.serial = serial;
        }
    }
}
